<template>
  <el-form :size="defaultFormItemSize" @submit.prevent label-position="top">
    <div
      class="business-operation-list"
      v-for="businessItem in businessOperationList"
      :key="businessItem.type"
    >
      <div class="name">{{ businessItem.name }}</div>
      <div class="desc">{{ businessItem.desc }}</div>
      <div
        class="business-operation-item"
        v-for="operation in businessItem.operationList"
        :key="operation.id"
      >
        <el-form-item label="">
          <el-row
            type="flex"
            justify="space-between"
            align="middle"
            style="flex-wrap: nowrap; width: 100%"
          >
            <el-radio-group v-model="operation.actionType" @change="updateBusinessOperationList">
              <el-radio value="SQL">SQL</el-radio>
              <el-radio value="EXPRESSION">EL表达式</el-radio>
              <el-radio value="HTTP">HTTP</el-radio>
            </el-radio-group>
            <el-icon
              style="cursor: pointer; color: #606266; font-size: 16px"
              @click="onDeleteVariable(businessItem, operation)"
            >
              <Delete />
            </el-icon>
          </el-row>
        </el-form-item>
        <el-form-item label="" v-if="operation.actionType === 'SQL'">
          <el-input
            v-model="operation.sql"
            type="textarea"
            placeholder="请输入SQL语句, 流程变量使用${}, 如: select * from t where id = ${businessKey}"
            @change="updateBusinessOperationList"
          />
        </el-form-item>
        <el-form-item label="" v-if="operation.actionType === 'EXPRESSION'">
          <el-input
            v-model="operation.expression"
            placeholder="请输入EL表达式, 如: ${flowApproveFunction.getDept(deptId)}"
            @change="updateBusinessOperationList"
          />
        </el-form-item>
        <el-form-item label="" v-if="operation.actionType === 'HTTP'">
          <ApiSetting
            :isBusiness="true"
            :model-value="getHttpJsonString(operation)"
            @update:modelValue="val => onHttpInfoChange(val, operation)"
          />
        </el-form-item>
      </div>
      <el-button
        type="default"
        style="margin-top: 5px"
        :size="defaultFormItemSize"
        @click="addOperation(businessItem)"
      >
        添加操作
      </el-button>
    </div>
  </el-form>
</template>

<script>
import { Delete } from '@element-plus/icons-vue';
import ApiSetting from '../task/task-components/ApiSetting.vue';
import { SysFlowEntryBindFormType } from '@/common/staticDict/flow';

export default {
  name: 'BusinessOperationList',
  props: {
    id: String,
    userTask: {
      type: Boolean,
      default: true,
    },
  },
  inject: ['flowEntry', 'prefix', 'templateVariableList'],
  provide() {
    return {
      getAllAutoVariableList: () => [...this.templateVariableList()],
    };
  },
  components: {
    ApiSetting,
    Delete,
  },
  data() {
    return {
      processOperation: {
        start_flow: {
          type: 'start_flow',
          name: '流程开始',
          desc: '流程实例发起时执行',
          operationList: [],
        },
        end_flow: {
          type: 'end_flow',
          name: '流程结束',
          desc: '流程实例结束时执行',
          operationList: [],
        },
      },
      businessOperation: {
        enter_task: {
          type: 'enter_task',
          name: '节点开始时更新',
          desc: '流程进入此节点且审批开始前执行(退回后再次进入也会执行)',
          operationList: [],
        },
        agree: {
          type: 'agree',
          name: '节点同意后更新',
          desc: '节点点击同意后执行',
          operationList: [],
        },
        refuse: {
          type: 'refuse',
          name: '节点驳回后更新',
          desc: '节点点击驳回或决绝后执行',
          operationList: [],
        },
        revoke: {
          type: 'revoke',
          name: '节点撤销后更新',
          desc: '节点被上一个节点撤回后执行',
          operationList: [],
        },
        multi_sign: {
          type: 'multi_sign',
          name: '会签过程中更新',
          desc: '会签节点多人审批时，在每个审批人处理后执行',
          operationList: [],
        },
      },
      elementBusinessOperationList: undefined,
    };
  },
  computed: {
    finalOperationList() {
      return this.userTask ? this.businessOperation : this.processOperation;
    },
    /**
     * 获取业务操作列表
     * @returns {Array} 返回包含所有业务操作的数组
     */
    businessOperationList() {
      return Object.keys(this.finalOperationList).map(key => {
        return this.finalOperationList[key];
      });
    },
  },
  methods: {
    onDeleteVariable(businessItem, operation) {
      let index = businessItem.operationList.findIndex(item => item.id === operation.id);
      if (index !== -1) {
        businessItem.operationList.splice(index, 1);
        this.updateBusinessOperationList();
      }
    },
    resetFormList() {
      this.bpmnELement = window.bpmnInstances.bpmnElement;
      let elExtensionElements =
        this.bpmnELement.businessObject.get('extensionElements') ||
        window.bpmnInstances.moddle.create('bpmn:ExtensionElements', { values: [] });
      this.elementBusinessOperationList =
        elExtensionElements.values.filter(
          ex => ex.$type === `${this.prefix}:BusinessOperationList`,
        )?.[0] ||
        window.bpmnInstances.moddle.create(`${this.prefix}:BusinessOperationList`, {
          businessOperationList: [],
        });
      console.log(this.elementBusinessOperationList);
      Object.keys(this.finalOperationList).forEach(key => {
        this.finalOperationList[key].operationList = [];
      });
      if (Array.isArray(this.elementBusinessOperationList.businessOperationList)) {
        this.elementBusinessOperationList.businessOperationList.forEach(operation => {
          if (operation && operation.data != null && operation.data !== '') {
            try {
              let temp = JSON.parse(operation.data);
              if (temp) {
                this.finalOperationList[temp.operationType].operationList.push(temp);
              }
            } catch (e) {
              console.error(e);
            }
          }
        });
      }
    },
    updateBusinessOperationList() {
      let elExtensionElements =
        this.bpmnELement.businessObject.get('extensionElements') ||
        window.bpmnInstances.moddle.create('bpmn:ExtensionElements', { values: [] });
      let otherExtensions = elExtensionElements.values.filter(
        ex => ex.$type !== `${this.prefix}:BusinessOperationList`,
      );
      this.elementBusinessOperationList.businessOperationList = [];
      Object.keys(this.finalOperationList).forEach(key => {
        this.finalOperationList[key].operationList.forEach(operation => {
          let data = JSON.stringify(operation);
          let tempElement = window.bpmnInstances.moddle.create(`${this.prefix}:Operation`, {
            data: data,
          });
          this.elementBusinessOperationList.businessOperationList.push(tempElement);
        });
      });
      const newElExtensionElements = window.bpmnInstances.moddle.create(`bpmn:ExtensionElements`, {
        values: otherExtensions.concat(this.elementBusinessOperationList),
      });
      // 更新到元素上
      window.bpmnInstances.modeling.updateProperties(this.bpmnELement, {
        extensionElements: newElExtensionElements,
      });
    },
    addOperation(businessItem) {
      businessItem.operationList.push({
        id: new Date().getTime(),
        operationType: businessItem.type,
        forOnlineTable:
          this.flowEntry().value.bindFormType === SysFlowEntryBindFormType.ONLINE_FORM,
        actionType: 'SQL',
        sql: '',
        expression: '',
        httpRequestInfo: {},
        httpResponnseData: {},
        processDefinitionKey: this.flowEntry().value.processDefinitionKey,
        dblinkId: this.flowEntry().value.dblinkId,
      });
      this.updateBusinessOperationList();
    },
    getHttpJsonString(operation) {
      return JSON.stringify({
        httpRequestInfo: operation.httpRequestInfo,
        httpResponnseData: operation.httpResponnseData,
      });
    },
    onHttpInfoChange(value, operation) {
      console.log(value);
      if (value == null || value === '') {
        operation.httpRequestInfo = {};
        operation.httpResponnseData = {};
      } else {
        let tempData = JSON.parse(value);
        operation.httpRequestInfo = tempData.httpRequestInfo;
        operation.httpResponnseData = tempData.httpResponnseData;
      }
      this.updateBusinessOperationList();
    },
  },
  watch: {
    id: {
      immediate: true,
      handler(val) {
        if (val && val.length) {
          this.$nextTick(() => {
            this.resetFormList();
          });
        }
      },
    },
  },
};
</script>

<style scoped>
.business-operation-list {
  margin-top: 15px;
}
.business-operation-list .name {
  font-size: 14px;
  font-weight: bold;
  color: #333333;
  margin: 8px 0px 5px 0px;
}
.business-operation-list .desc {
  font-size: 14px;
  color: #666666;
  margin-bottom: 10px;
}
.business-operation-item + .business-operation-item {
  margin-top: 15px;
  border-top: 1px solid #dcdfe6;
}
</style>
